﻿using System;
using System.Collections.Generic;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Architecture;
using Autodesk.Revit.UI;
using YJKGeometryFuncs;
using YJKRevitStairs.StairsModel.CommonUnit;
using YJKRevitStairs.StairsModel.DataInfos;

namespace YJKRevitStairs.StairsModel.Manage
{
	public class DoubleBranchParallelStairsCreator : StairsCreator
	{
		public DoubleBranchParallelStairsCreator(ExternalCommandData commandData) : base(commandData)
		{
		}

		private double CalcStairTopElevation(DoubleBranchParallelStairs param_stairs)
		{
			return param_stairs.m_dTopOffset + param_stairs.m_dLevelValue + param_stairs.m_dBottomElevation;
		}

		private ElementId EditStairs(DoubleBranchParallelStairs param_stairs, ElementId bottomLevelId, ElementId topLevelId)
		{
			ElementId elementId = null;
			LineRunData leftRunData = param_stairs.m_LeftRunData;
			using (StairsEditScope stairsEditScope = new StairsEditScope(this.m_Document, "Stairs Automation"))
			{
				elementId = stairsEditScope.Start(bottomLevelId, topLevelId);
				Stairs stairs = this.m_Document.GetElement(elementId) as Stairs;
				using (Transaction transaction = new Transaction(this.m_Document, "Stairs Automation"))
				{
					transaction.Start();
					RunInfo runInfo = default(RunInfo);
					runInfo.RunWidth = param_stairs.getStairsWidth();
					runInfo.TreadDepth = leftRunData.TreadDepth;
					runInfo.TreadHeight = leftRunData.TreadHeight;
					runInfo.TreadThickness = leftRunData.TreadThickness;
					runInfo.RunStructalDepth = leftRunData.RunStructualDepth;
					runInfo.RiserThickness = leftRunData.RiserThickness;
					if (param_stairs.m_listSupport.Count > 0)
					{
						BaseSupportData baseSupportData = param_stairs.m_listSupport[0];
					}
					if (param_stairs.m_listRail.Count > 0)
					{
						BaseRaillingData baseRaillingData = param_stairs.m_listRail[0];
					}
					if (!base.ChangeStairsType(stairs, leftRunData.TheStairsType, runInfo, param_stairs.m_sName, param_stairs.m_LandData.LandingThickness))
					{
						transaction.RollBack();
						stairsEditScope.Cancel();
						return null;
					}
					try
					{
						double num = 0.0;
						if (param_stairs.m_listRunCurve.Count == 3)
						{
							if (param_stairs.m_bIsCenterUp)
							{
								SingleRunCurveInfo runConstructionInfo = param_stairs.m_listRunCurve[0];
								num = StairsRunCreator.CreateStairsRun(elementId, this.m_Document, ConstValueManager.StairStartElevation, runConstructionInfo).get_Parameter(BuiltInParameter.STAIRS_RUN_HEIGHT).AsDouble();
								runConstructionInfo = param_stairs.m_listRunCurve[1];
								StairsRunCreator.CreateStairsRun(elementId, this.m_Document, num, runConstructionInfo);
								runConstructionInfo = param_stairs.m_listRunCurve[2];
								StairsRunCreator.CreateStairsRun(elementId, this.m_Document, num, runConstructionInfo);
							}
							else
							{
								SingleRunCurveInfo runConstructionInfo2 = param_stairs.m_listRunCurve[0];
								num = StairsRunCreator.CreateStairsRun(elementId, this.m_Document, ConstValueManager.StairStartElevation, runConstructionInfo2).get_Parameter(BuiltInParameter.STAIRS_RUN_HEIGHT).AsDouble();
								runConstructionInfo2 = param_stairs.m_listRunCurve[1];
								StairsRunCreator.CreateStairsRun(elementId, this.m_Document, ConstValueManager.StairStartElevation, runConstructionInfo2);
								runConstructionInfo2 = param_stairs.m_listRunCurve[2];
								StairsRunCreator.CreateStairsRun(elementId, this.m_Document, num, runConstructionInfo2);
							}
						}
						foreach (LandingCurveInfo landingCurveInfo in param_stairs.m_listLandCurve)
						{
							StairsLandingCreator.CreateLanding(stairs.Id, this.m_Document, num, landingCurveInfo.m_arCurveInfo);
						}
						StairsUsingRangeXdata.WriteStairsUsingRange(stairs, param_stairs.m_sUsingRange);
					}
					catch (Exception)
					{
						transaction.RollBack();
						stairsEditScope.Cancel();
						return null;
					}
					XYZ vecTrans = new XYZ(param_stairs.m_ptPosition.X, param_stairs.m_ptPosition.Y, 0.0);
					base.TranslationStairs(stairs, vecTrans, param_stairs.m_ptRealInsert, param_stairs.m_dBottomOffset, param_stairs.m_dTopOffset);
					stairs.DesiredRisersNumber = stairs.ActualRisersNumber;
					transaction.Commit();
					double dSupportWidth = Common.MMToFeet(50.0);
					if (param_stairs.m_listSupport.Count > 0)
					{
						dSupportWidth = base.GetSupportTypeWidth(param_stairs.m_listSupport[0].SupportType);
					}
					base.SetDefaultSurpportType(stairs, param_stairs.m_listSupport);
					List<ElementId> stairsOutsupportIds = base.GetStairsOutsupportIds(stairs, param_stairs.m_listOutSupportPoints, dSupportWidth);
					base.ChangeSupportType(stairs, param_stairs.m_listSupport, stairsOutsupportIds);
				}
				stairsEditScope.Commit(new StairsEditScopeFailuresPreprocessor());
			}
			return elementId;
		}

		private void ChangeStairsBeamElevation(Autodesk.Revit.DB.Document doc, Stairs stairs, ref DoubleBranchParallelStairs param_stairs)
		{
			StairsRunManager stairsRunManager = new StairsRunManager(this.m_Document, stairs);
			double baseElevation = stairs.BaseElevation;
			double stairsTreadThickness = stairsRunManager.GetStairsTreadThickness();
			double stairsTreadHeight = stairsRunManager.GetStairsTreadHeight();
			double stairsRunTopElevation = stairsRunManager.GetStairsRunTopElevation(0, baseElevation);
			double stairsRunTopElevation2 = stairsRunManager.GetStairsRunTopElevation(1, baseElevation);
			double dElevation = stairsRunTopElevation - stairsTreadThickness;
			double dElevation2 = stairsRunTopElevation2 - stairsTreadThickness;
			base.SetBeamElevation(ref param_stairs.m_listBeamCurve, BeamType.BT_Bottom, 0, baseElevation + stairsTreadHeight - stairsTreadThickness);
			base.SetBeamElevation(ref param_stairs.m_listBeamCurve, BeamType.BT_Mid, 1, dElevation);
			base.SetBeamElevation(ref param_stairs.m_listBeamCurve, BeamType.BT_Land, 1, dElevation);
			base.SetBeamElevation(ref param_stairs.m_listBeamCurve, BeamType.BT_Top, 2, dElevation2);
			base.SetTopBeamRealLocation(ref param_stairs.m_listBeamCurve, stairsRunManager, 0.0);
			double beamWidth = param_stairs.m_BeamData.BeamWidth;
			base.SetBottomBeamRealLocation(ref param_stairs.m_listBeamCurve, stairsRunManager, beamWidth);
		}

		public bool CreateDoubleBranchParallelStairs(DoubleBranchParallelStairs param_stairs)
		{
			ElementId elementId = null;
			ElementId elementId2 = null;
			LineRunData leftRunData = param_stairs.m_LeftRunData;
			LineRunData midRunData = param_stairs.m_MidRunData;
			LineRunData rightRunData = param_stairs.m_RightRunData;
			double bottomElevation = param_stairs.m_dBottomElevation + param_stairs.m_dBottomOffset;
			double topElevation = this.CalcStairTopElevation(param_stairs);
			ElementId elementId3 = null;
			double dBottomOffset = 0.0;
			double dTopOffset = 0.0;
			if (!base.GetLevel(bottomElevation, topElevation, ref elementId, ref elementId2, ref dBottomOffset, ref dTopOffset, param_stairs.m_dTopOffset, ref elementId3) || !base.StairsLevelIsValid(elementId, elementId2))
			{
				return false;
			}
			param_stairs.m_dBottomOffset = dBottomOffset;
			param_stairs.m_dTopOffset = dTopOffset;
			ElementId elementId4 = this.EditStairs(param_stairs, elementId, elementId2);
			if (!base.IsStairsValid(elementId4))
			{
				return false;
			}
			base.ShowStairsPath(elementId4, param_stairs.m_bNoteUpStairs);
			Stairs stairs = this.m_Document.GetElement(elementId4) as Stairs;
			if (!base.ChangeRailingType(stairs, param_stairs.m_listRail))
			{
				return false;
			}
			using (Transaction transaction = new Transaction(this.m_Document, "Stairs Beam"))
			{
				transaction.Start();
				List<string> arLandWidth = param_stairs.m_arLandWidth;
				string sStairsLand = ElementXDataManager.m_sStairsLand;
				if (arLandWidth != null)
				{
					base.WriteStairsLandWidthXData(stairs, "StairsXData", sStairsLand, arLandWidth);
				}
				this.ChangeStairsBeamElevation(this.m_Document, stairs, ref param_stairs);
				StairsBeamCreator.CreateStairsBeam(this.m_Document, this.m_RevitVersion, param_stairs.m_BeamData, param_stairs.m_listBeamCurve, param_stairs.m_ptPosition, stairs, param_stairs.m_ptRealInsert);
				ElementXDataManager.CommitStairsXData(stairs);
				transaction.Commit();
			}
			base.RotateStairs(stairs, param_stairs.m_ptRealInsert);
			base.SetStairsBottomFloorVisibility(stairs, param_stairs.m_FloorType, this.m_Document.ActiveView, base.CreateStairBottomVisibleBuiltInCate());
			double height = stairs.Height;
			if (elementId3 != null)
			{
				base.DelLevel(elementId3);
			}
			if (!YJKGeometryFuncs.Geometry.IsEqual(stairs.Height, height, 0.0001))
			{
				using (Transaction transaction2 = new Transaction(this.m_Document, "CorrectStairsHeight"))
				{
					transaction2.Start();
					stairs.Height = height;
					transaction2.Commit();
				}
			}
			return true;
		}
	}
}
